// DesignExtractor.h : DesignExtractor is used to store all the data into the tables.
// Author: Achyut P Balaji
//
#ifndef DESIGN_EXTRACTOR_H
#define DESIGN_EXTRACTOR_H

#include<iostream>
#include<string>
#include<vector>
#include"../TABLES/VarTable.h"
#include"../TABLES/ModifyVarTable.h"
#include"../TABLES/ModifyStatTable.h"
#include"../TABLES/ModifyProcTable.h"
#include"../TABLES/ProcTable.h"
#include"../../SPA_Data_Types.h"
#include"../TABLES/CallsTable.h"
#include"../TABLES/StatTable.h"
#include"../TABLES/UsesStatTable.h"
#include"../TABLES/UsesVarTable.h"
#include"../TABLES/UsesProcTable.h"
#include"../AST/AST_Query.h"

using namespace std;

enum BLOCK_TYPE {BLOCK_WHILE,BLOCK_IF};

class DesignExtractor {
private:
	AST_Query *astquery;
	VarTable* varTable;
	ProcTable* procTable;
	StatTable* statTable;
	ModifyVarTable* modifyVar;
	ModifyStatTable* modifyStat;
	ModifyProcTable* modifyProc;
	UsesVarTable* usesVar;
	UsesStatTable* usesStat;
	UsesProcTable* usesProc;
	CallsTable* callsTable;
	string str;
	vector<VAR_INDEX> RHS_LIST;
public:

	DesignExtractor() {
		AST *a = AST::getInstance();
		this->astquery = new AST_Query(a);
		varTable = VarTable::getInstance();
		procTable = ProcTable::getInstance();
		statTable = StatTable::getInstance();
		modifyVar = ModifyVarTable::getFirstInstance();
		modifyStat = ModifyStatTable::getFirstInstance();
		modifyProc = ModifyProcTable::getFirstInstance();
		usesVar = UsesVarTable::getFirstInstance();
		usesStat = UsesStatTable::getFirstInstance(statTable->getNoofStmts(),varTable->getTotalSize());
		usesProc = UsesProcTable::getFirstInstance();
		callsTable = CallsTable::getFirstInstance();
		procTable->initial();
		modifyProc->initial(procTable->getSize());
		usesProc->initial(procTable->getSize());
		modifyVar->initialise(varTable->getTotalSize());
		usesVar->initialise(varTable->getTotalSize());
		callsTable->initialise(procTable->getSize());
	};


	BOOLEAN fillTable();
	void parseExpr(stack<STRING> *s, expr *e);
	void getPattern(STRING &p, stack<STRING> *s, expr *e);
	void getModifyUsesList(STATEMENT_INDEX blockNo, vector<VAR_INDEX> &usedVar, vector<VAR_INDEX> &modifiedVar,BLOCK_TYPE type);
	void insertCallsData(vector<PROC_INDEX> callStmt);
	void getNextStmts(STMT_VCTR &stmtVector);

};

#endif